﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Drawing;
using Microsoft.VisualBasic;

namespace XdbHelper
{
    public partial class MainForm : Form
    {
        public Dictionary<string,string> worddic = new Dictionary<string,string>();
        public string Ver = "  v1.00";
        public class ComponentItem {
            public XmlElement rootElement;
            public XmlElement inheritElement;
            public List<ComponentItem> AllProperty = new List<ComponentItem>();
            public ComponentItem NextNode;//下一个节点
        }
        public Dictionary<string, XmlElement> keyValuePairs = new Dictionary<string, XmlElement>();
        //加载的xml
        public Stream DataSourceSream;
        public List<ComponentItem> baseInheritElement = new List<ComponentItem>();

        public XmlDocument customerDocument = new XmlDocument();

        public XmlElement copyElement;
        public MainForm()
        {
            InitDictionary();
            InitializeComponent();
            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
            string fileName = assembly.GetName().Name + ".Res.Database.xml";
            DataSourceSream = assembly.GetManifestResourceStream(fileName);
            byte[] StreamData = new byte[DataSourceSream.Length];
            DataSourceSream.Read(StreamData, 0, (int)DataSourceSream.Length);
            MemoryStream memoryStream = new MemoryStream(StreamData);
            XmlReader xmlReader= XmlReader.Create(memoryStream);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(xmlReader);
            //获取所有组件信息
            XmlNodeList xmlNodeList = xmlDocument.GetElementsByTagName("ComponentTemplate");
            foreach (XmlElement element in xmlNodeList) {
                keyValuePairs.Add(element.GetAttribute("Guid"),element);
            }
            XmlNodeList xmlNodeList2 = xmlDocument.GetElementsByTagName("EntityTemplate");
            foreach (XmlElement element in xmlNodeList2)
            {
                keyValuePairs.Add(element.GetAttribute("Guid"), element);
            }
            XmlNodeList xmlNodeList3 = xmlDocument.GetElementsByTagName("SubsystemTemplate");
            foreach (XmlElement element in xmlNodeList3)
            {
                keyValuePairs.Add(element.GetAttribute("Guid"), element);
            }
            XmlNodeList xmlNodeList4 = xmlDocument.GetElementsByTagName("ParameterSet");
            foreach (XmlElement element in xmlNodeList4)
            {
                if (element.HasAttribute("Value")) keyValuePairs.Add(element.GetAttribute("Guid"), element);
            }
            XmlNodeList xmlNodeList5 = xmlDocument.GetElementsByTagName("Parameter");
            foreach (XmlElement element in xmlNodeList5)
            {
                string guid = element.GetAttribute("Guid");
                if(element.HasAttribute("Value"))keyValuePairs.Add(guid, element);
            }

            foreach (XmlElement xmlElement in keyValuePairs.Values) {
                ComponentItem componentItem = new ComponentItem();
                if (!xmlElement.HasAttribute("InheritanceParent"))
                { //基础组件
                    componentItem.rootElement = xmlElement;
                    foreach (XmlElement xmlElement1 in xmlElement.ChildNodes)
                    {
                        ComponentItem componentItem1 = new ComponentItem() { rootElement = xmlElement1 };
                        if (xmlElement1.HasAttribute("InheritanceParent"))
                        {
                            GetAllItems(componentItem1, xmlElement1);
                        }
                        componentItem.AllProperty.Add(componentItem1);
                    }
                }
                else
                {
                    GetAllItems(componentItem,xmlElement);
                }
                baseInheritElement.Add(componentItem);
            }
            Text += Ver;
            InitTreeView();
        }
        public void InitDictionary() {
            worddic.Add("MemberComponentTemplate", "生物组件项");
            worddic.Add("Parameter","单个参数项");
            worddic.Add("ParameterSet", "多个参数项");
            worddic.Add("EntityTemplate","实体项");
            worddic.Add("ComponentTemplate","组件模板项");
            worddic.Add("Class", "源码中的类名(带命名空间)");
            worddic.Add("SlotsCount", "箱子的格子数");
            worddic.Add("ActiveSlotIndex", "激活的格子位置");
            worddic.Add("JumpStrength", "跳跃强度");
            worddic.Add("AlwaysEnabled", "始终自动跳跃");
            worddic.Add("FlySpeed", "飞行速度");
            worddic.Add("Position", "位置");
            worddic.Add("Rotation", "旋转");
            worddic.Add("ModelName", "模型名称");
            worddic.Add("DiggingCracks", "挖掘动画");
            worddic.Add("Mount", "骑马或乘船(挂载)");
            worddic.Add("DismountOffset", "下马或下船位置");
            worddic.Add("MountOffset", "上马或上船位置");
            worddic.Add("Flu", "感冒");
            worddic.Add("FluDuration", "感冒周期");
            worddic.Add("FluOnset", "流感开始发作时间");
            worddic.Add("Health", "生命组件");
            worddic.Add("AttackResilience", "最大生命值");
            worddic.Add("FallResilience", "掉落抗性");
            worddic.Add("FireResilience", "燃烧抗性");
            worddic.Add("CauseOfDeath", "死亡原因");
            worddic.Add("BreathingMode", "呼吸模式");
            worddic.Add("Inventory", "箱子组");




        }
        public void InitTreeView() {
            treeView1.Nodes.Clear();
            TreeNode treeNode1 = new TreeNode() { Text = "组件模板" };
            TreeNode treeNode2 = new TreeNode() { Text = "实体模板" };
            TreeNode treeNode3 = new TreeNode() { Text = "子系统模板" };
            for (int i=0;i<baseInheritElement.Count;i++) {
                ComponentItem componentItem = baseInheritElement[i];
                TreeNode treeNode = new TreeNode();
                GetAllNodes(treeNode,componentItem);
                if (componentItem.rootElement.Name == "ComponentTemplate") treeNode1.Nodes.Add(treeNode);
                if (componentItem.rootElement.Name == "EntityTemplate") treeNode2.Nodes.Add(treeNode);
                if (componentItem.rootElement.Name == "SubsystemTemplate") treeNode3.Nodes.Add(treeNode);
            }
            treeView1.LabelEdit = false;
            treeView1.Nodes.Add(treeNode1);
            treeView1.Nodes.Add(treeNode2);
            treeView1.Nodes.Add(treeNode3);
            treeView1.NodeMouseClick +=new TreeNodeMouseClickEventHandler( (a,b) => {
                TreeNode treeNode = treeView1.GetNodeAt(b.X,b.Y);
                ComponentItem componentItem = (ComponentItem)treeNode.Tag;
                if (componentItem != null) {
                    label7.Text = componentItem.rootElement.Name;
                    if (worddic.TryGetValue(label7.Text, out string text))
                    {
                        label8.Text = text;
                        if (treeNode.Parent != null) {
                            ComponentItem componentItem2 = (ComponentItem)treeNode.Parent.Tag;
                            if (componentItem2 != null) {
                                if (worddic.TryGetValue(componentItem2.rootElement.Name, out string text4)) {
                                    if (text4 == text) label8.Text += "(继承项)";
                                }
                            }
                        }
                    }
                    else label8.Text = "暂无对应说明";


                    if (componentItem.rootElement.HasAttribute("Name")) label11.Text = componentItem.rootElement.GetAttribute("Name"); else label11.Text = string.Empty;
                    if (componentItem.rootElement.HasAttribute("Value"))
                    {
                        label9.Text = componentItem.rootElement.GetAttribute("Value");
                    }
                    else label9.Text = string.Empty;

                    if (componentItem.rootElement.HasAttribute("new-Value"))
                    {
                        label9.Text = componentItem.rootElement.GetAttribute("new-Value") + "(重写)";
                    }
                    string guid = componentItem.rootElement.GetAttribute("Guid");
                    if (!string.IsNullOrEmpty(guid)) label13.Text = FindGuid(treeNode, guid);
                    else label13.Text = string.Empty;
                    if (worddic.TryGetValue(label11.Text, out string text2))
                    {
                        label15.Text = text2;
                    }
                    else label15.Text = string.Empty;

                    SetMenu(componentItem.rootElement, treeNode);
                }
            });
            treeView2.NodeMouseClick += new TreeNodeMouseClickEventHandler((a,b)=> {
                TreeNode treeNode = treeView2.GetNodeAt(b.X, b.Y);
                treeView2.SelectedNode = treeNode;
                ComponentItem componentItem = (ComponentItem)treeNode.Tag;
                if (componentItem != null)
                {
                    label7.Text = componentItem.rootElement.Name;
                    if (worddic.TryGetValue(label7.Text, out string text))
                    {
                        label8.Text = text;
                        if (treeNode.Parent != null)
                        {
                            ComponentItem componentItem2 = (ComponentItem)treeNode.Parent.Tag;
                            if (componentItem2 != null)
                            {
                                if (worddic.TryGetValue(componentItem2.rootElement.Name, out string text2))
                                {
                                    if (text2 == text) label8.Text += "(继承项)";
                                }
                            }
                        }
                    }
                    else label8.Text = "暂无对应说明";
                    if (componentItem.rootElement.HasAttribute("Name")) label11.Text = componentItem.rootElement.GetAttribute("Name"); else label11.Text = string.Empty;
                    if (componentItem.rootElement.HasAttribute("Value")) {
                        label9.Text = componentItem.rootElement.GetAttribute("Value");
                    }else label9.Text = string.Empty;

                    if (componentItem.rootElement.HasAttribute("new-Value"))
                    {
                        label9.Text = componentItem.rootElement.GetAttribute("new-Value") + "(重写)";
                    }
                    string guid = componentItem.rootElement.GetAttribute("Guid");
                    if (!string.IsNullOrEmpty(guid)) label13.Text = FindGuid(treeNode, guid);
                    else label13.Text = string.Empty;
                    SetMenu(componentItem.rootElement, treeNode);
                }
            });
        }
        public void InitCustomerTreeView() {
            treeView2.Nodes.Clear();
            XmlElement xmlElement1 = customerDocument.CreateElement("Folder");
            xmlElement1.SetAttribute("Name", "Components");
            xmlElement1.SetAttribute("Guid", "766da18a-636a-4a88-803c-4462aed106f3");

            XmlElement xmlElement2 = customerDocument.CreateElement("Folder");
            xmlElement2.SetAttribute("Name", "Entities");
            xmlElement2.SetAttribute("Guid", "5fcdf35f-7001-442c-883e-e0502b15d291");

            XmlElement xmlElement3 = customerDocument.CreateElement("Folder");
            xmlElement3.SetAttribute("Name", "Subsystems");
            xmlElement3.SetAttribute("Guid", "75acb50b-fb75-4c85-af38-a0fb51a9eb90");

            XmlElement xmlElement4 = customerDocument.CreateElement("Override");
            customerDocument.FirstChild.AppendChild(xmlElement1);
            customerDocument.FirstChild.AppendChild(xmlElement2);
            customerDocument.FirstChild.AppendChild(xmlElement3);
            customerDocument.FirstChild.AppendChild(xmlElement4);

            ComponentItem zujian = new ComponentItem() { rootElement = xmlElement1 };
            ComponentItem shiti = new ComponentItem() { rootElement = xmlElement2 };
            ComponentItem zixit = new ComponentItem() { rootElement = xmlElement3 };
            ComponentItem chx = new ComponentItem() { rootElement = xmlElement4 };

            TreeNode treeNode1 = new TreeNode() { Text = "组件模板", Tag = zujian };
            SetMenu(xmlElement1, treeNode1);
            TreeNode treeNode2 = new TreeNode() { Text = "实体模板", Tag = shiti };
            SetMenu(xmlElement2, treeNode2);
            TreeNode treeNode3 = new TreeNode() { Text = "子系统模板", Tag = zixit };
            SetMenu(xmlElement3, treeNode3);
            TreeNode treeNode4 = new TreeNode() { Text = "原版内容重写", Tag = chx };
            SetMenu(xmlElement4, treeNode4);

            treeView2.Nodes.Add(treeNode1);
            treeView2.Nodes.Add(treeNode2);
            treeView2.Nodes.Add(treeNode3);
            treeView2.Nodes.Add(treeNode4);
        }


        public void GetAllNodes(TreeNode treeNode, ComponentItem item)
        {
            ComponentItem componentItem = item;
            treeNode.Text = componentItem.rootElement.GetAttribute("Name");
            SetMenu(item.rootElement, treeNode);
            treeNode.Tag = componentItem;
            if (componentItem.NextNode != null )
            {
                TreeNode treeNode1 = new TreeNode();
                GetAllNodes(treeNode1, componentItem.NextNode);
                treeNode1.Tag = componentItem.NextNode;
                treeNode.Nodes.Add(treeNode1);
                treeNode.ForeColor = Color.Red;
            }
            else treeNode.ForeColor = Color.Blue;
            if (componentItem.AllProperty.Count > 0)
            {
                for (int j = 0; j < componentItem.AllProperty.Count; j++)
                {
                    ComponentItem componentItem1 = componentItem.AllProperty[j];
                    XmlElement xml = componentItem1.rootElement;
                    TreeNode treeNode1 = new TreeNode();
                    if (componentItem1.NextNode != null)
                    {
                        TreeNode treeNode2 = new TreeNode();
                        treeNode2.Tag = componentItem1.NextNode;
                        GetAllNodes(treeNode2, componentItem1.NextNode);
                        treeNode1.Nodes.Add(treeNode2);
                        treeNode1.ForeColor = Color.Red;

                    }else if (componentItem1.rootElement.ChildNodes.Count > 0) {

                        foreach (XmlElement xmlElement in componentItem1.rootElement.ChildNodes) {
                            TreeNode treeNode2 = new TreeNode();
                            SetMenu(item.rootElement, treeNode2);
                            treeNode2.ForeColor = Color.Red;
                            treeNode2.Tag = new ComponentItem() {rootElement=xmlElement };
                            treeNode2.Text = xmlElement.GetAttribute("Name");
                            treeNode1.Nodes.Add(treeNode2);
                        }
                    }
                    else treeNode1.ForeColor = Color.Blue;
                    treeNode1.Tag = componentItem1;
                    SetMenu(xml, treeNode1);
                    treeNode1.ForeColor = Color.Green;
                    treeNode1.Text = componentItem1.rootElement.GetAttribute("Name");
                    treeNode.Nodes.Add(treeNode1);
                }

            }
        }
        public void SetMenu(XmlElement xml,TreeNode treeNode) {
            if (treeNode.ContextMenu == null) treeNode.ContextMenu = new ContextMenu();
            else treeNode.ContextMenu.MenuItems.Clear();
            treeNode.ContextMenu.MenuItems.Add(new MenuItem("查看标签", new EventHandler((a, b) => { MessageBox.Show(xml.Name); })));
            if (xml.HasAttribute("Description"))
            {
                treeNode.ContextMenu.MenuItems.Add(new MenuItem("查看描述", new EventHandler((a, b) => { MessageBox.Show(xml.GetAttribute("Description")); })));
                treeNode.ContextMenu.MenuItems.Add(new MenuItem("编辑描述", new EventHandler((a, b) => {
                    InputDialog inputDialog = new InputDialog("编辑属性值", xml.GetAttribute("Description"),(text, f) => {
                        if (f)
                        {
                            xml.SetAttribute("Description", text);
                        }
                    });
                    inputDialog.Show();
                })));
            }
            if (xml.HasAttribute("Value")) {
                treeNode.ContextMenu.MenuItems.Add(new MenuItem("查看属性值", new EventHandler((a, b) => { MessageBox.Show(xml.GetAttribute("Value")); })));
                treeNode.ContextMenu.MenuItems.Add(new MenuItem("编辑属性值", new EventHandler((a, b) => {
                    InputDialog inputDialog = new InputDialog("编辑属性值", xml.GetAttribute("Value"), (text,f)=> {
                        if (f) {
                            xml.SetAttribute("Value", text);
                        }
                    });
                    inputDialog.Show();
                })));
                treeNode.ContextMenu.MenuItems.Add(new MenuItem("重写属性值", new EventHandler((a, b) => {
                    InputDialog inputDialog = new InputDialog("重写属性值", xml.GetAttribute("Value"), (text, f) => {
                        if (f)
                        {
                            xml.SetAttribute("new-Value", text);
                        }
                    });
                    inputDialog.Show();
                })));
                if (xml.HasAttribute("new-Value")){
                    treeNode.ContextMenu.MenuItems.Add(new MenuItem("定位重写的内容", new EventHandler((a, b) => {

                        foreach (TreeNode treeNode1 in treeView1.Nodes) {
                            FindGuid(treeNode1, xml.GetAttribute("Guid"));
                        }
                    })));
                }
            }
            treeNode.ContextMenu.MenuItems.Add(new MenuItem("刷新Guid", new EventHandler((a, b) => {                 
                ComponentItem componentItem = (ComponentItem)treeNode.Tag;
                if (componentItem != null)
                {
                    ReGuid(componentItem.rootElement);
                    MessageBox.Show("Guid刷新成功");
                    if (componentItem.rootElement.HasAttribute("Guid")) componentItem.rootElement.SetAttribute("Guid", MakeGuid());
                }
                else {
                    MessageBox.Show("Guid刷新失败");
                }
            })));
            treeNode.ContextMenu.MenuItems.Add(new MenuItem("粘贴到该节点", new EventHandler((a, b) => {
                if (copyElement != null)
                {
                    TreeNode treeNode2 = new TreeNode();
                    ComponentItem componentItem = new ComponentItem();
                    componentItem.rootElement = copyElement;
                    if (componentItem != null) {
                        GetAllItems(componentItem, copyElement);
                        GetAllNodes(treeNode2, componentItem);
                        treeNode.Nodes.Add(treeNode2);
                        copyElement = null;
                    }
                }
            })));
            treeNode.ContextMenu.MenuItems.Add(new MenuItem("删除该节点", new EventHandler((a, b) => { treeNode.Remove(); })));
            treeNode.ContextMenu.MenuItems.Add(new MenuItem("复制该节点", new EventHandler((a, b) => { copyElement = xml; })));
        }

        public string FindGuid(TreeNode treeNode,string guid) {
            return FindGuidLogic(guid);
        }
        public string FindGuidLogic(string guid)
        {
            if (keyValuePairs.TryGetValue(guid, out XmlElement xmlElement)) {
                if (xmlElement.HasAttribute("Value")) return xmlElement.GetAttribute("Value");
            }
            return string.Empty;
        }

        public void ReGuid(XmlElement xmlElement) {
            foreach (XmlElement xml in xmlElement.ChildNodes) {
                if (xml.HasAttribute("Guid")) xml.SetAttribute("Guid",MakeGuid());
                if (xml.ChildNodes.Count > 0) ReGuid(xml);
            }              
        }
        public void GetAllItems(ComponentItem item,XmlElement thisElement) {

            if (thisElement.HasAttribute("InheritanceParent")) {

                string inheritGuid = thisElement.GetAttribute("InheritanceParent");
                item.rootElement = thisElement;
                if (keyValuePairs.TryGetValue(inheritGuid, out XmlElement xml))
                {
                    item.inheritElement = xml;
                    if (xml.HasAttribute("InheritanceParent"))
                    { //有下一个节点
                        item.NextNode = new ComponentItem();
                        GetAllItems(item.NextNode, xml);//遍历节点
                    }
                }

            }

            //获取子元素集
            foreach (XmlElement element in thisElement.ChildNodes) {
                ComponentItem componentItem = new ComponentItem();
                componentItem.rootElement = element;
                if (element.HasAttribute("InheritanceParent"))
                {
                    string inheritGuid1 = element.GetAttribute("InheritanceParent");
                    if (keyValuePairs.TryGetValue(inheritGuid1, out XmlElement xml1))
                    {
                        componentItem.inheritElement = xml1;
                        if (xml1.HasAttribute("InheritanceParent"))
                        { //有下一个节点
                            componentItem.NextNode = new ComponentItem();
                            GetAllItems(componentItem.NextNode, xml1);//遍历节点
                        }
                    }
                }else if (element.ChildNodes.Count > 0)
                {
                    foreach (XmlElement xmlElement in element.ChildNodes)
                    {
                        ComponentItem component = new ComponentItem();
                        component.rootElement = xmlElement;
                        componentItem.AllProperty.Add(component);
                    }
                }
                item.AllProperty.Add(componentItem);
            }
        }



        private void MainForm_Load(object sender, EventArgs e)
        {
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("红色表示有子集，蓝色表示无子集，绿色表示属性");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                MessageBox.Show("请输入名称");
            }
            else {
                customerDocument.LoadXml($"<{textBox1.Text}></{textBox1.Text}>");
                label2.Text = $"新建[{textBox1.Text}]";
                InitCustomerTreeView();
            }
        }
        public string MakeGuid() {
            return Guid.NewGuid().ToString();        
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (customerDocument.DocumentElement == null)
            {
                MessageBox.Show("请先创建一个新的");
            }
            else {
                foreach (TreeNode treeNode in treeView2.Nodes) {
                    ComponentItem componentItem = (ComponentItem)treeNode.Tag;
                    if (componentItem != null)
                    {
                        if (treeNode.Text == "原版内容重写")
                        {
                            SaveToXml(treeNode, customerDocument.DocumentElement);
                        }
                        else {
                            SaveToXml(treeNode, componentItem.rootElement);

                        }
                    }
                }
                File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, customerDocument.DocumentElement.Name + ".xdb"), customerDocument.OuterXml);
                MessageBox.Show("导出成功");
            }
        }
        public void SaveToXml(TreeNode treeNode,XmlElement xmlElement) {
            foreach (TreeNode treeNode1 in treeNode.Nodes) {
                ComponentItem componentItem = (ComponentItem)treeNode1.Tag;
                if (componentItem != null)
                {
                    xmlElement.InnerXml=componentItem.rootElement.OuterXml;
                }
            }
        }


    }
}
